package getHardInfo

import (
	"encoding/json"
	"io"

	"log"
	"os"
	"path/filepath"
	rundebug "runtime/debug"
	"time"

	jsonvalue "github.com/Andrew-M-C/go.jsonvalue"

	"golang.org/x/sys/windows/svc"
)

/*
sc create myservice binPath= "C:\Users\myservice.exe"

sc create myservice binpath= "c:\myservice\myservice.exe" start= auto
sc description myservice "IT台账硬件信息收集"


sc start myservice
sc config myservice start= auto

sc stop myservice
sc delete myservice
*/

var Igetset func(name string, value interface{}) interface{} //函数变量 并且共享

var start time.Time //上一次执行时间

type 主服务业务 struct{} //主服务业务

func (m *主服务业务) Execute(args []string, req <-chan svc.ChangeRequest, status chan<- svc.Status) (svcSpecificEC bool, exitCode uint32) {
	const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
	status <- svc.Status{State: svc.StartPending}
	status <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}

	ticker := time.NewTicker(1 * time.Minute)
	defer ticker.Stop()

loop:
	for {
		select {
		case <-ticker.C: //一分钟来一次
			// log.Printf("服务 is ticker.C  %v", start)
			if 定期执行网关(start) {
				start = time.Now()
				I定期执行()
			}
		case c := <-req:
			switch c.Cmd {
			case svc.Interrogate:
				status <- c.CurrentStatus
				log.Printf("服务 is svc.Interrogate ")
			case svc.Stop, svc.Shutdown:
				log.Printf("服务 is svc.Stop, svc.Shutdown ")
				break loop
			default:
				log.Printf("未知控制命令 #%d", c)
			}
		}
	}

	status <- svc.Status{State: svc.StopPending}
	return
}
func 定期执行网关(tm time.Time) bool {
	//返回是否可执行
	var ret bool
	//间隔上报
	cfgPath := Igetset("cfgPath", nil).(string)
	cfg := I读取json配置文件(cfgPath) //jo对象
	upstep, err := cfg.GetInt("上报间隔")
	if err != nil {
		log.Printf(" 读取配置 上报间隔 =:   %v\n %s \n", err, rundebug.Stack())
		log.Printf(" 使用默认值 60 现值 =:   %v\n %v \n", upstep, upstep)
		upstep = 60
	}
	duration := tm.Sub(time.Now())           //上一次执行时间 time.Now()
	if int(duration.Minutes())*-1 > upstep { //60>1
		ret = true
	} else {
		ret = false
	}
	//---
	log.Printf("时间差.分钟 %v 整数 %v 间隔%v  %v\n", duration.Minutes(), int(duration.Minutes())*-1, upstep, ret)
	return ret
}
func I定期执行test() {
	//测试  后台定期执行
	log.Printf("I定期执行2   %v   ", Igetset("cfgPath", nil))
	cfgPath := Igetset("cfgPath", nil).(string)
	cfg := I读取json配置文件(cfgPath) //jo对象
	硬件信息dc := I硬件信息()           //直接读取不依赖其他
	str, err := cfg.GetString("名称")
	if err != nil {
		log.Printf(" json解析错误 =:   %v\n %s \n", err, rundebug.Stack())
	} else {
		str = "未知"
	}
	硬件信息dc["来着用户"] = str                                      //加入时间
	硬件信息dc["生成时间"] = time.Now().Format("2006-01-02 15:04:05") //加入时间
	//log.Printf(" 查看 硬件信息dc 字典的值：【%v】\n", 硬件信息dc)
	mjson, _ := json.Marshal(硬件信息dc)
	log.Printf("json 硬件信息 :%s\n", string(mjson))
	log.Printf("json 配置信息 :%v\n", cfg)
	log.Printf("I定期执行3 ")
}
func I定期执行() {
	/*
	 再服务 端定期调用后执行 ，并有提交数据功能
	*/
	cfgPath := Igetset("cfgPath", nil).(string)
	cfg := I读取json配置文件(cfgPath)
	uname, err := cfg.GetString("名称")
	if err != nil {
		log.Printf("  读取json 值 名称 =:   %v\n %s \n", err, rundebug.Stack())
	}

	//--获取信息
	硬件信息dc := I硬件信息()
	硬件信息dc["来着用户"] = uname                                    //加入时间
	硬件信息dc["生成时间"] = time.Now().Format("2006-01-02 15:04:05") //加入时间
	//log.Printf(" 查看 硬件信息dc 字典的值：【%v】\n", 硬件信息dc)
	// mjson, _ := json.Marshal(硬件信息dc)
	// log.Printf("json 硬件信息 :%s\n", string(mjson))
	binDir := Igetset("binDir", nil).(string)
	I写json文件(硬件信息dc, filepath.Join(binDir, "硬件信息.json"))
	//--提交上报
	macAddr := 硬件信息dc["网卡地址"].(string)
	postUrl, err := cfg.GetString("上报地址")
	if err != nil {
		log.Printf(" 读取json 值 上报地址 =:   %v\n %s \n", err, rundebug.Stack())
	}
	go Posthttp(硬件信息dc, postUrl+uname+","+macAddr)
}

func S系统服务程序() {
	isIntSess, err := svc.IsAnInteractiveSession()
	if err != nil {
		log.Printf(" 初始化 系统服务会话: %v\n %s \n", err, rundebug.Stack())
	}
	if !isIntSess {
		log.Printf("系统服务-启动时间 at %v %s", isIntSess, time.Now())
		系统服务程序("注册到系统的服务名字", false)
		log.Printf("系统服务-关闭时间 at %v %s", isIntSess, time.Now())

	}
	log.Printf(" 完成系统服务会话: %v\n  ", isIntSess)
}
func 系统服务程序(name string, isDebug bool) {
	var err error
	log.Printf("系统服务程序 name %s", name)
	run := svc.Run
	err = run(name, &主服务业务{}) //loop运行中？？
	if err != nil {
		log.Printf("系统服务 %s 程序出错  %v\n %s \n", name, err, rundebug.Stack())
	}
	log.Printf("系统服务程序 name %s 结束！！！", name)

}

func removeBOM(data []byte) []byte {
	if len(data) >= 3 && data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF {
		return data[3:]
	}
	return data
}

func I读取json配置文件(cfgFile string) *jsonvalue.V {
	var obj *jsonvalue.V //数据类型

	//log.Printf("读取配置文件 ：%v ", cfgFile)
	//打开文件
	file, err := os.Open(cfgFile) //有BOM头的UTF8文件
	if err != nil {
		log.Printf("打开cfg.json 配置文件错误 路径 %v =: %v\n %s\n", cfgFile, err, rundebug.Stack())
		return obj
	}
	defer file.Close()

	// 读取内容
	data, err := io.ReadAll(file) //ioutil.ReadFile
	if err != nil {

		log.Printf("读取cfg.json 配置文件错误: %v\n %s\n", err, rundebug.Stack())
		return obj
	}
	data = removeBOM(data)
	// 解析 JSON 数据
	obj, err = jsonvalue.Unmarshal(data)
	if err != nil {

		log.Printf("解析 JSON内容出错: %v\n %s\n", err, rundebug.Stack())
		return obj
	}

	return obj
}
func I写json文件(mobj map[string]interface{}, filePath string) {

	// 打开文件
	file, err := os.Create(filePath)
	if err != nil {
		log.Fatal(err) //退出
	}
	defer file.Close()

	// 创建 JSON 编码器
	encoder := json.NewEncoder(file)
	encoder.SetEscapeHTML(false)
	//encoder.SetEscapeHTML(true)

	// 将 map 变量编码为 JSON 并写入文件
	if err := encoder.Encode(mobj); err != nil {
		log.Fatal(err) //退出
	}

}
